package com.shrfid.rfidsdk.entity;


import com.shrfid.rfidsdk.uitls.ReadTagUtils;

import java.nio.ByteBuffer;

/**
 * 请求数据帧
 */
public class RequestFrame {

    /**
     * 帧头
     */
    private static final byte FRAME_HEADER = 0X05;

//    /**
//     * 天线ID
//     */
//    private static final byte ADDRESS = 0X01;

    private byte sof;           //帧头
    private byte len;           //帧长度(除sof字段外所有长度)
    private byte address;       //天线地址,0xff代表广播
    private byte[] cmd;         //命令
    private byte[] params;      //参数
    private byte[] crc;         //crc校验数据

    private RequestFrame(byte sof, byte len, byte address, byte[] cmd, byte[] params, byte[] crc) {
        this.sof = sof;
        this.len = len;
        this.address = address;
        this.cmd = cmd;
        this.params = params;
        this.crc = crc;
    }

    public byte[] toBytes() {
        ByteBuffer buffer = ByteBuffer.allocate(len + 1);//长度不包括sof,所以这里要+1
        buffer.put(sof);
        buffer.put(len);
        buffer.put(address);
        buffer.put(cmd);
        if (params != null) {
            buffer.put(params);
        }
        buffer.put(crc);
        return buffer.array();
    }

    /**
     * 根据滚码+命令生成key作为查询返回结果的索引
     *
     * @return key
     */
    public String generateKey() {
        ByteBuffer buffer = ByteBuffer.allocate(3);
        buffer.put(address);
        buffer.put(cmd);
        return ReadTagUtils.bytesToHexString(buffer.array());
    }

    public static class Builder {
        private byte sof;           //帧头
        private byte len;           //帧长度
        private byte address;       //天线地址,0xff代表广播
        private byte[] cmd;         //命令
        private byte[] params;      //参数
        private byte[] crc;         //crc校验数据

//        public Builder sof(byte sof) {
//            this.sof = sof;
//            return this;
//        }

        public Builder address(byte address) {
            this.address = address;
            return this;
        }

        public Builder cmd(byte[] cmd) {
            this.cmd = cmd;
            return this;
        }

        public Builder params(byte[] params) {
            this.params = params;
            return this;
        }

        public RequestFrame build() {
            //校验数据
            if (cmd == null || cmd.length != 2) {
                throw new RuntimeException("cmd 格式错误");
            }

            //赋默认值
            sof = FRAME_HEADER;

            //计算长度()
            byte paramLen = (byte) (params == null ? 0 : params.length);
            len = (byte) (paramLen + 6);

            //计算crc
            ByteBuffer buffer = ByteBuffer.allocate(len - 2);//不包含sof和crc长度
            buffer.put(len);
            buffer.put(address);
            buffer.put(cmd);
            if (params != null) {
                buffer.put(params);
            }
            byte[] crcArray = buffer.array();
            crc = ReadTagUtils.calCrc16(crcArray);

            return new RequestFrame(sof, len, address, cmd, params, crc);
        }
    }
}
